#include <vector>
#include <iostream>

#include"priority_queue.h"

using namespace std;

void test_priority_queue1()
{
    qds::priority_queue<int> pr_qu;

    pr_qu.push(1);
    pr_qu.push(2);
    pr_qu.push(3);
    pr_qu.push(4);
    pr_qu.push(5);

    while(!pr_qu.empty())
    {
        cout << pr_qu.top() << endl;
        pr_qu.pop();
    }

    cout << endl;

    vector<int> v1{2,3,4,5,6,7,8};
    qds::priority_queue<int> pr_qu1(v1.begin(), v1.end());

    while(!pr_qu1.empty())
    {
        cout << pr_qu1.top() << endl;
        pr_qu1.pop();
    }

}

template<class T>
struct Less 
{
    bool operator()(const T& x, const T& y)
    {
        return x < y;
    }
};

template<class T>
struct Greater
{
    bool operator()(const T& x, const T& y)
    {
        return x > y;
    }
};

//仿函数(functor)，就是使一个类的使用看上去像一个函数
//其实现就是类中实现一个operator()，这个类就有了类似函数的行为
//就是一个仿函数类了。
void test_functor()
{
    //Less叫做仿函数类型,less叫做函数对象
    Less<int> less;
    cout << less(1, 2) << endl;
    cout << Less<int>()(1, 2) << endl;
    cout << Less<double>()(2.2, 1.1) << endl;

    Greater<int> greater;
    cout << greater(1, 2) << endl;
    cout << Greater<int>()(1, 2) << endl;
    cout << Greater<double>()(3.3, 2.2) << endl;

}

void test_priority_queue2()
{
    //qds::priority_queue<int, vector<int>, less<int>> pr_qu;
    qds::priority_queue<int, vector<int>, qds::greater<int>> pr_qu;

    pr_qu.push(1);
    pr_qu.push(2);
    pr_qu.push(3);
    pr_qu.push(4);
    pr_qu.push(5);

    while(!pr_qu.empty())
    {
        cout << pr_qu.top() << endl;
        pr_qu.pop();
    }

    cout << endl;

    vector<int> v1{2,3,4,5,6,7,8};
    //qds::priority_queue<int, vector<int>, less<int>> pr_qu1(v1.begin(), v1.end());
    qds::priority_queue<int, vector<int>, qds::greater<int>> pr_qu1(v1.begin(), v1.end());

    while(!pr_qu1.empty())
    {
        cout << pr_qu1.top() << endl;
        pr_qu1.pop();
    }

}


ostream& operator<<(ostream& _cout, const Date& d)
{
    cout << d._year << "-" << d._month << "-" << d._day;
    return _cout;
}

//如果数据类型,不支持比较,或者比较的方式不是你想要的
//那么可以自己实现仿函数,按照自己的方式去比较,控制比较逻辑
void test_date1()
{
    Date d1(2020, 10, 4);
    Date d2(2019, 6, 7);
    Date d3(2017, 9, 10);
    Date d4(2022, 10, 4);

    qds::priority_queue<Date, vector<Date>, qds::greater<Date>> pr_qu1;
    pr_qu1.push(d1);
    pr_qu1.push(d2);
    pr_qu1.push(d3);
    pr_qu1.push(d4);

    while(!pr_qu1.empty())
    {
        cout << pr_qu1.top() << endl;
        pr_qu1.pop();
    }
}

struct less_date_ptr
{
    bool operator()(const Date* d1, const Date* d2) const
    {
        return (d1->_year < d2->_year) || 
            (d1->_year == d2->_year && d1->_month < d2->_month) ||
            (d1->_year == d2->_year && d1->_month == d2->_month && d1->_day < d2->_day);
    }
};

struct greater_date_ptr
{
    bool operator()(const Date* d1, const Date* d2) const
    {
        return (d1->_year > d2->_year) || 
            (d1->_year == d2->_year && d1->_month > d2->_month) ||
            (d1->_year == d2->_year && d1->_month == d2->_month && d1->_day > d2->_day);
    }
};

void test_date2()
{
    //如果优先级队列里面保存的是对象的指针
    //但是比较的时候,肯定是按照对象的大小来进行比较的
    //这种情况怎么处理?
    //1.自己写仿函数去控制
    //2.写好的仿函数模板特化
    
    Date* d1 = new Date(2020, 10, 4);
    Date* d2 = new Date(2019, 6, 7);
    Date* d3 = new Date(2017, 9, 10);
    Date* d4 = new Date(2022, 10, 4);
    
    //自己写仿函数去控制
    //qds::priority_queue<Date*, vector<Date*>, less_date_ptr> pr_qu1;
    //qds::priority_queue<Date*, vector<Date*>, greater_date_ptr> pr_qu1;
    
    //写好仿函数去模板特化
    //qds::priority_queue<Date*, vector<Date*>, qds::greater<Date*>> pr_qu1;
    qds::priority_queue<Date*, vector<Date*>, qds::less<Date*>> pr_qu1;
    pr_qu1.push(d1);
    pr_qu1.push(d2);
    pr_qu1.push(d3);
    pr_qu1.push(d4);

    while(!pr_qu1.empty())
    {
        cout << (*pr_qu1.top()) << endl;
        pr_qu1.pop();
    }

}

int main()
{
    //test_priority_queue1();
    
    //test_functor();
    
    //test_priority_queue2();
    
    //test_date1();
    
    test_date2();
    return 0;
}
